<?php

namespace App\Service;

use App\Helper\SizeConversionHelper;
use App\Model\ImagesInfo;
use Exception;
use Throwable;

readonly class ImageInfoProvider implements ImageInfoProviderInterface
{
    private const SRC_ATTR = 'src';

    public function __construct(private ImageParserInterface $imageParser)
    {
    }

    public function getImagesInfo(string $url): ImagesInfo
    {
        $this->prepareUrl($url);

        $imageNodes= $this->imageParser->getImageNodesByUrl($url);

        $totalFileSize = 0;
        $imagesUrl = [];

        foreach ($imageNodes as $node) {
            try {
                $src = $node->getAttribute(self::SRC_ATTR);
                $fileUrl = $this->extractDomainFromUrl($url) . $src;

                $imagesSize = $this->getImageSizeByUrl($fileUrl);
                if ($imagesSize === null) {
                    continue;
                }

            } catch (Throwable) {
                continue;
            }

            $totalFileSize += $imagesSize;
            $imagesUrl[] = $fileUrl;
        }

        return new ImagesInfo(count($imagesUrl), SizeConversionHelper::bytesToMb($totalFileSize), $imagesUrl);
    }

    private function getImageSizeByUrl(string $url)
    {
        return (get_headers($url, 1))['Content-Length'] ?? null;
    }

    private function prepareUrl(string &$url): void
    {
        if (str_ends_with($url, '/')) {
            $url = rtrim($url, '/');
        }
    }

    /**
     * @throws Exception
     */
    function extractDomainFromUrl($url): false|string
    {
        $parsedUrl = parse_url($url);
        if ($parsedUrl === false ||!isset($parsedUrl['host'])) {
            throw new Exception('Не удалось получить хост');
        }
        return "{$parsedUrl['scheme']}://{$parsedUrl['host']}";
    }
}
